package dataContracts;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;

import util.ChecksumHelper;
import util.Logger;
import util.SerializationHelper;

public class SharedDirectory implements Serializable {
	private static final long serialVersionUID = -4705681266996364063L;
	// the directory file handle
	protected transient File directory;
	protected transient SerializationHelper<DirectoryInfo> _serializer;
	
	public DirectoryInfo directoryInfo;
	
	public SharedDirectory(String directoryPath) {
		directoryInfo = new DirectoryInfo();
		setFilePath(directoryPath);
		directory = new File(getFilePath());
		setFiles(new ArrayList<SharedFile>());
		setLastModified(directory.lastModified());
		
		_serializer = new SerializationHelper<DirectoryInfo>();
	}
	
	public transient String filePath;
	public void setFilePath(String filePath) {
		this.filePath = filePath;
	}
	public String getFilePath() {
		return filePath;
	}
	
	private Date lastModified;
	public boolean setLastModified(Date lastModified) {
		if (directory.setLastModified(lastModified.getTime())) {
			this.lastModified = lastModified;
			return true;
		}
		
		return false;
	}
	public void setLastModified(long lastModified) {
		this.lastModified = new Date(lastModified);
	}
	public Date getLastModified() {
		return lastModified;
	}
	
	public String getDirectoryChecksum() {
		// this calculates the checksum in realtime... we probably want to change this...
		return directoryInfo.checksum;
	}
	public void updateDirectoryChecksum() {
		if (directory.exists()) {
			directoryInfo.checksum = ChecksumHelper.GetChecksum(directory);
		}
	}
	
	// this is the checksum of the serialized object, not the files on disk
	private String checksum;
	public String getChecksum() {
		if (directory != null)
			updateDirectoryChecksum();
		
		checksum = directoryInfo.checksum;
		
		return checksum;
	}

	public ArrayList<SharedFile> files;
	public void setFiles(ArrayList<SharedFile> files) {
		this.files = files;
	}
	public ArrayList<SharedFile> getFiles() {
		return files;
	}
	
	public boolean isLocked() {
		return directoryInfo.isLocked;
	}
	public void Lock() {
		directoryInfo.isLocked = true;
	}
	
	// this should be callable anytime... just makes sure all the checksums and stuff are fresh
	public void refresh() {
		setLastModified(directory.lastModified());
		
		directoryInfo.files = new ArrayList<FileInfo>();
    	for (SharedFile sf : files) {
    		sf.refresh();
    		directoryInfo.files.add(sf.fileState);
		}
		
		updateDirectoryChecksum();	
	}
	
	public DirectoryInfo getDirectoryInfo() {
		directoryInfo.files = new ArrayList<FileInfo>();
		for (SharedFile file : files) {
			directoryInfo.files.add(file.fileState);
		}
		
		return directoryInfo;
	}

	public boolean fileExists(String fileName) {
		return findFile(fileName) == null;
	}
	
	public SharedFile getFile(SharedFile file) {
		return findFile(file.getName());
	}
	
	public SharedFile findFile(String file) {
		SharedFile match = null;
		
		for (SharedFile f : files) {
			if (f == null)
				continue;
			
			if (f.getName().equalsIgnoreCase(file)) {
				match = f;
				break;
			}
		}
		
		return match;
	}
	
	// hard delete: remove the file and all references from the directory
	public void deleteFile(String path) {
		SharedFile f = findFile(path);
		
		if (f != null) {
			files.remove(f);
			if (f.getFileReference().delete()) {
				Logger.Debug("File Deleted: "+ f.getName());
			} else {
				Logger.Debug("File FAILED Delete: "+ f.getName());
			}
		} else {
			Logger.Debug("Just couldn't find you're file: "+ path);
		}
	}
}